#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
期末周 - 网页版游戏
使用Flask框架实现网页版本
"""

from flask import Flask, render_template, request, jsonify, session
import json
import random
import os

# 导入游戏控制器和模型
from controllers.game_controller import WebGameController
from models.player import Player

app = Flask(__name__, 
           static_folder=os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static'),
           template_folder=os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates'))
app.secret_key = 'finals_week_secret_key_2025'

# 确保静态文件目录存在
static_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static')
cg_dir = os.path.join(static_dir, 'cg')
if not os.path.exists(cg_dir):
    os.makedirs(cg_dir)

# 创建游戏控制器实例
game_controller = WebGameController()

@app.route('/')
def index():
    """主页"""
    return render_template('game.html')

@app.route('/api/start_new_game', methods=['POST'])
def start_new_game():
    """开始新游戏"""
    # 获取选择的老师类型，默认为和蔼的老师
    data = request.get_json()
    teacher_type = data.get('teacher_type', 'kind') if data else 'kind'
    
    game_state = game_controller.start_new_game(teacher_type)
    session['game_state'] = game_state
    return jsonify(game_state)

@app.route('/api/load_game', methods=['POST'])
def load_game():
    """加载游戏"""
    try:
        if os.path.exists("savegame.json"):
            with open("savegame.json", "r", encoding="utf-8") as f:
                game_state = json.load(f)
            session['game_state'] = game_state
            return jsonify({'success': True, 'game_state': game_state})
        else:
            return jsonify({'success': False, 'message': '没有找到存档文件！'})
    except Exception as e:
        return jsonify({'success': False, 'message': f'存档损坏或无法读取: {str(e)}'})

@app.route('/api/save_game', methods=['POST'])
def save_game():
    """保存游戏"""
    game_state = session.get('game_state')
    if game_state:
        try:
            with open("savegame.json", "w", encoding="utf-8") as f:
                json.dump(game_state, f, ensure_ascii=False, indent=2)
            return jsonify({'success': True})
        except Exception as e:
            return jsonify({'success': False, 'message': f'保存失败: {str(e)}'})
    return jsonify({'success': False, 'message': '没有可保存的游戏状态'})

@app.route('/api/get_game_state', methods=['GET'])
def get_game_state():
    """获取当前游戏状态"""
    game_state = session.get('game_state')
    if game_state:
        return jsonify(game_state)
    return jsonify({'error': '没有进行中的游戏'})

@app.route('/api/next_day', methods=['POST'])
def next_day():
    """进入下一天"""
    game_state = session.get('game_state')
    if not game_state:
        return jsonify({'error': '没有进行中的游戏'})
    
    day = game_state['day']
    if day > game_controller.max_days or game_state['game_over']:
        # 游戏结束
        game_state['game_over'] = True
        session['game_state'] = game_state
        return jsonify({
            'type': 'game_end',
            'game_state': game_state
        })
    
    # 重置随堂测试标记
    game_state['quiz_taken'] = False
    
    # 调整玩家状态：精力值增加30%，知识值减少60%
    player = Player()
    player.from_dict(game_state['player'])
    
    # 精力值增加30%
    player.energy = min(100, int(player.energy * 1.3))
    
    # 知识值减少60%
    player.knowledge = max(0, int(player.knowledge * 0.4))
    
    # 更新游戏状态中的玩家数据
    game_state['player'] = player.to_dict()
    
    # 触发随机事件
    event = game_controller.trigger_random_event()
    
    # 随机获得道具，传入玩家背包以防止重复获得相同物品
    item = game_controller.find_random_item(player.inventory)
    
    # 如果获得道具，将其添加到玩家背包中
    if item:
        player.inventory.append(item)
        game_state['player'] = player.to_dict()
    
    # 获取当天考试
    exam = game_controller.exams[day - 1]
    
    # 重置当天操作次数
    game_state['actions_today'] = 0
    
    result = {
        'type': 'day_start',
        'day': day,
        'exam': exam,
        'event': event,
        'item': item,
        'game_state': game_state
    }
    
    session['game_state'] = game_state
    return jsonify(result)

@app.route('/api/trigger_random_event', methods=['POST'])
def trigger_random_event():
    """触发随机事件"""
    game_state = session.get('game_state')
    if not game_state:
        return jsonify({'error': '没有进行中的游戏'})
    
    # 触发随机事件
    event = game_controller.trigger_random_event()
    
    # 随机获得道具，传入玩家背包以防止重复获得相同物品
    player = Player()
    player.from_dict(game_state['player'])
    item = game_controller.find_random_item(player.inventory)
    
    # 如果获得道具，将其添加到玩家背包中
    if item:
        player.inventory.append(item)
        game_state['player'] = player.to_dict()
    
    result = {
        'event': event,
        'item': item,
        'game_state': game_state
    }
    
    session['game_state'] = game_state
    return jsonify(result)

# 添加一个检查并增加操作次数的辅助函数
def check_and_increment_action(action_type=None):
    """检查并增加操作次数"""
    game_state = session.get('game_state')
    if not game_state:
        return {'error': '没有进行中的游戏'}
    
    # 检查是否超过每日操作次数限制
    if 'actions_today' not in game_state:
        game_state['actions_today'] = 0
    
    # 特殊操作类型（考试、使用道具和处理事件）不受次数限制
    # 但处理事件接受操作需要消耗次数
    if action_type in ['exam', 'use_item', 'use_exam_item', 'decline_event', 'quiz']:
        # 这些操作不消耗行动次数
        # 增加操作次数（即使是特殊操作也计数）
        # 不增加计数，因为这些操作不消耗次数
        return {'success': True}
    
    # 普通操作受次数限制（复习、休息、接受事件）
    if game_state['actions_today'] >= game_controller.max_actions_per_day:
        return {'success': False, 'message': f'每天只能进行{game_controller.max_actions_per_day}次操作！考试时间到了，不能进行别的操作了哦'}
    
    # 增加操作次数
    game_state['actions_today'] += 1
    session['game_state'] = game_state
    return {'success': True}

@app.route('/api/study', methods=['POST'])
def study():
    """复习功课"""
    # 检查操作次数
    action_check = check_and_increment_action('study')
    if not action_check['success']:
        return jsonify(action_check)
    
    game_state = session.get('game_state')
    if not game_state:
        return jsonify({'error': '没有进行中的游戏'})
    
    player = Player()
    player.from_dict(game_state['player'])
    
    # 根据选择的老师类型调整学习效果
    teacher_type = game_state.get('teacher_type', 'kind')  # 默认为和蔼的老师
    
    energy_cost = 10
    knowledge_gain = 15
    
    # 如果选择了严厉但是很好的老师
    if teacher_type == 'strict':
        energy_cost = 15
        knowledge_gain = 20
    
    if player.energy < energy_cost:
        return jsonify({
            'success': False,
            'message': '你的精力不足，无法复习功课！',
            'player': player.to_dict()
        })
    
    player.energy -= energy_cost
    player.knowledge += knowledge_gain
    
    game_state['player'] = player.to_dict()
    session['game_state'] = game_state
    
    # 根据老师类型返回不同的消息
    if teacher_type == 'strict':
        message = '你花时间复习功课，在严厉老师的指导下，精力减少15点，知识增加20点！'
    else:
        message = '你花时间复习功课，精力减少10点，知识增加15点！'
    
    return jsonify({
        'success': True,
        'message': message,
        'player': player.to_dict(),
        'actions_today': game_state['actions_today']
    })

@app.route('/api/rest', methods=['POST'])
def rest():
    """休息恢复"""
    # 检查操作次数
    action_check = check_and_increment_action('rest')
    if not action_check['success']:
        return jsonify(action_check)
    
    game_state = session.get('game_state')
    if not game_state:
        return jsonify({'error': '没有进行中的游戏'})
    
    player = Player()
    player.from_dict(game_state['player'])
    
    player.energy = min(100, player.energy + 20)
    player.knowledge = max(0, player.knowledge - 5)
    
    game_state['player'] = player.to_dict()
    session['game_state'] = game_state
    
    return jsonify({
        'success': True,
        'message': '你选择休息恢复精力，知识减少5点，精力增加20点！',
        'player': player.to_dict(),
        'actions_today': game_state['actions_today']
    })

@app.route('/api/study_with_questions', methods=['POST'])
def study_with_questions():
    """带问题的学习"""
    # 检查操作次数
    action_check = check_and_increment_action('study')
    if not action_check['success']:
        return jsonify(action_check)
    
    game_state = session.get('game_state')
    if not game_state:
        return jsonify({'error': '没有进行中的游戏'})
    
    # 获取当前天数对应的科目
    day = game_state['day']
    if day > len(game_controller.exams):
        subject = None
        subject_name = "综合"
    else:
        subject = game_controller.exams[day-1]
        subject_name = subject['name']
    
    # 生成相关问题
    question = game_controller.get_study_question(subject_name if subject else None)
    
    return jsonify({
        'success': True,
        'question': question,
        'subject': subject_name if subject else "综合",
        'actions_today': game_state['actions_today']
    })

@app.route('/api/answer_study_question', methods=['POST'])
def answer_study_question():
    """回答学习问题"""
    game_state = session.get('game_state')
    if not game_state:
        return jsonify({'error': '没有进行中的游戏'})
    
    data = request.json
    selected_option = data.get('selected_option')
    correct_answer = data.get('correct_answer')
    
    player = Player()
    player.from_dict(game_state['player'])
    
    # 根据选择的老师类型调整学习效果
    teacher_type = game_state.get('teacher_type', 'kind')  # 默认为和蔼的老师
    
    energy_cost = 10
    base_knowledge_gain = 10
    bonus_knowledge_gain = 10  # 答对额外奖励
    
    # 如果选择了严厉但是很好的老师
    if teacher_type == 'strict':
        energy_cost = 15
        base_knowledge_gain = 15
        bonus_knowledge_gain = 15
    
    if player.energy < energy_cost:
        return jsonify({
            'success': False,
            'message': '你的精力不足，无法学习！',
            'player': player.to_dict()
        })
    
    # 扣除精力值
    player.energy -= energy_cost
    
    # 增加基础知识点
    player.knowledge += base_knowledge_gain
    
    # 检查答案是否正确
    is_correct = (selected_option == correct_answer)
    message = ""
    
    if is_correct:
        # 答对了，额外奖励知识点
        player.knowledge += bonus_knowledge_gain
        if teacher_type == 'strict':
            message = f'你认真学习并答对了问题！精力减少{energy_cost}点，知识增加{base_knowledge_gain + bonus_knowledge_gain}点！'
        else:
            message = f'你认真学习并答对了问题！精力减少{energy_cost}点，知识增加{base_knowledge_gain + bonus_knowledge_gain}点！'
    else:
        if teacher_type == 'strict':
            message = f'你认真学习但答错了问题，在严厉老师的指导下仍获得了知识。精力减少{energy_cost}点，知识增加{base_knowledge_gain}点！'
        else:
            message = f'你认真学习但答错了问题，不过还是学到了知识。精力减少{energy_cost}点，知识增加{base_knowledge_gain}点！'
    
    game_state['player'] = player.to_dict()
    session['game_state'] = game_state
    
    return jsonify({
        'success': True,
        'message': message,
        'is_correct': is_correct,
        'player': player.to_dict(),
        'actions_today': game_state['actions_today']
    })

@app.route('/api/use_item', methods=['POST'])
def use_item():
    """使用道具"""
    # 检查操作次数
    action_check = check_and_increment_action('use_item')
    if not action_check['success']:
        return jsonify(action_check)
    
    game_state = session.get('game_state')
    if not game_state:
        return jsonify({'error': '没有进行中的游戏'})
    
    data = request.json
    item_index = data.get('item_index')
    
    player = Player()
    player.from_dict(game_state['player'])
    
    if item_index < 0 or item_index >= len(player.inventory):
        return jsonify({
            'success': False,
            'message': '无效的道具选择',
            'player': player.to_dict()
        })
    
    item = player.inventory[item_index]
    effect_desc = ""
    
    if item["effect"] == "energy":
        player.energy += item["value"]
        if item["id"] == "coffee":
            player.health -= 5
            effect_desc = f"恢复{item['value']}点精力，但损失5点生命值！"
        else:
            effect_desc = f"恢复{item['value']}点精力！"
    elif item["effect"] == "knowledge":
        player.knowledge += item["value"]
        effect_desc = f"知识增加{item['value']}点！"
    elif item["effect"] == "luck":
        effect_desc = "幸运值提升，在考试中可能会有帮助！"
    elif item["effect"] == "exam":
        effect_desc = "这只能在考试中使用！"
        return jsonify({
            'success': False,
            'message': effect_desc,
            'player': player.to_dict()
        })
    
    # 从背包中移除使用的道具
    player.inventory.pop(item_index)
    
    game_state['player'] = player.to_dict()
    session['game_state'] = game_state
    
    return jsonify({
        'success': True,
        'message': f"你使用了 {item['name']}! {effect_desc}",
        'player': player.to_dict(),
        'actions_today': game_state['actions_today']
    })

@app.route('/api/take_exam', methods=['POST'])
def take_exam():
    """参加考试"""
    # 检查操作次数
    action_check = check_and_increment_action('exam')
    if not action_check['success']:
        return jsonify(action_check)
    
    game_state = session.get('game_state')
    if not game_state:
        return jsonify({'error': '没有进行中的游戏'})
    
    player = Player()
    player.from_dict(game_state['player'])
    
    day = game_state['day']
    exam = game_controller.exams[day - 1]
    
    # 计算基础分数 (修改换算率为1:1)
    base_score = max(0, int(player.knowledge * 1.0) - (exam["difficulty"] * 5))
    
    return jsonify({
        'type': 'exam',
        'exam': exam,
        'base_score': base_score,
        'player': player.to_dict(),
        'actions_today': game_state['actions_today']
    })

@app.route('/api/complete_exam', methods=['POST'])
def complete_exam():
    """完成考试"""
    game_state = session.get('game_state')
    if not game_state:
        return jsonify({'error': '没有进行中的游戏'})
    
    data = request.json
    item_bonus = data.get('item_bonus', 0)
    
    player = Player()
    player.from_dict(game_state['player'])
    
    day = game_state['day']
    exam = game_controller.exams[day - 1]
    
    # 计算基础分数 (修改换算率为1:1)
    base_score = max(0, int(player.knowledge * 1.0) - (exam["difficulty"] * 5))
    
    # 完成考试
    result = game_controller.complete_exam(player, exam, base_score, item_bonus)
    
    # 检查是否还有生命值
    if player.health <= 0:
        game_state['game_over'] = True
        result['game_over'] = True
    else:
        # 准备进入下一天
        game_state['day'] += 1
        
        # 每天结束后恢复一些精力
        player.energy = min(100, player.energy + 10)
        
        # 更新游戏状态
        game_state['player'] = player.to_dict()
    
    session['game_state'] = game_state
    
    result['player'] = player.to_dict()
    result['day_complete'] = True
    result['next_day'] = game_state['day']
    
    return jsonify(result)

@app.route('/api/use_exam_item', methods=['POST'])
def use_exam_item():
    """使用考试道具"""
    game_state = session.get('game_state')
    if not game_state:
        return jsonify({'error': '没有进行中的游戏'})
    
    data = request.json
    item_index = data.get('item_index')
    
    player = Player()
    player.from_dict(game_state['player'])
    
    exam_items = [item for item in player.inventory if item["effect"] == "exam"]
    
    if item_index < 0 or item_index >= len(exam_items):
        return jsonify({
            'success': False,
            'message': '无效的道具选择'
        })
    
    # 找到在背包中的实际索引
    actual_index = next(i for i, inv_item in enumerate(player.inventory) 
                        if inv_item["id"] == exam_items[item_index]["id"])
    
    item = player.inventory[actual_index]
    
    # 从背包中移除使用的道具
    player.inventory.pop(actual_index)
    
    game_state['player'] = player.to_dict()
    session['game_state'] = game_state
    
    return jsonify({
        'success': True,
        'message': f"你使用了 {item['name']}! 分数增加 {item['value']} 分!",
        'bonus': item['value'],
        'player': player.to_dict()
    })


@app.route('/api/take_quiz', methods=['POST'])
def take_quiz():
    """进行随堂测试"""
    game_state = session.get('game_state')
    if not game_state:
        return jsonify({'error': '没有进行中的游戏'})
    
    # 检查今天是否已经进行过随堂测试
    if game_state.get('quiz_taken', False):
        return jsonify({
            'success': False,
            'message': '今天已经进行过随堂测试了！'
        })
    
    player = Player()
    player.from_dict(game_state['player'])
    
    # 获取当天考试科目
    day = game_state['day']
    exam = game_controller.exams[day - 1] if 1 <= day <= len(game_controller.exams) else None
    exam_subject = exam['name'] if exam else None
    
    # 标记今天已进行随堂测试
    game_state['quiz_taken'] = True
    session['game_state'] = game_state
    
    # 获取与当天考试科目相关的测试题目
    question = game_controller.take_quiz(player, exam_subject)
    
    return jsonify({
        'success': True,
        'question': question,
        'player': player.to_dict()
    })

@app.route('/api/answer_quiz', methods=['POST'])
def answer_quiz():
    """回答随堂测试问题"""
    game_state = session.get('game_state')
    if not game_state:
        return jsonify({'error': '没有进行中的游戏'})
    
    data = request.get_json()
    selected_answer = data.get('answer')
    correct_answer = data.get('correct_answer')
    
    player = Player()
    player.from_dict(game_state['player'])
    
    result = {
        'success': True,
        'correct': selected_answer == correct_answer,
        'player': player.to_dict()
    }
    
    if selected_answer == correct_answer:
        # 答对了，获得随机道具
        item = game_controller.find_random_item(player.inventory)
        if item:
            player.inventory.append(item)
            result['item'] = item
            result['message'] = f'回答正确！你获得了道具：{item["name"]}'
        else:
            result['message'] = '回答正确！但没有获得道具'
    else:
        # 答错了，扣除10点生命值
        player.health = max(0, player.health - 10)
        result['message'] = '回答错误！扣除10点生命值'
    
    # 更新玩家状态
    game_state['player'] = player.to_dict()
    session['game_state'] = game_state
    
    return jsonify(result)

@app.route('/api/process_event', methods=['POST'])
def process_event():
    """处理特殊事件"""
    # 检查操作次数（接受事件消耗操作次数，但自动处理事件除外）
    game_state = session.get('game_state')
    if not game_state:
        return jsonify({'error': '没有进行中的游戏'})
    
    data = request.json
    event_name = data.get('event_name')
    
    # 对于自动处理的事件（如"网络崩溃"），不消耗操作次数
    auto_processed_events = ["网络崩溃"]
    if event_name not in auto_processed_events:
        # 检查操作次数（接受事件消耗操作次数）
        action_check = check_and_increment_action('accept_event')  # 标记为接受事件操作
        if not action_check['success']:
            return jsonify(action_check)
    
    player = Player()
    player.from_dict(game_state['player'])
    
    # 处理特殊事件
    result = game_controller.process_special_event(event_name, player)
    
    # 如果获得了道具，添加到背包
    if result["item"]:
        player.inventory.append(result["item"])
    
    # 更新游戏状态
    game_state['player'] = player.to_dict()
    session['game_state'] = game_state
    
    result['actions_today'] = game_state['actions_today']
    
    return jsonify({
        'success': True,
        'message': result["message"],
        'player': player.to_dict(),
        'item': result["item"],
        'actions_today': game_state['actions_today']
    })


if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)